import threading
from datetime import datetime
from time import sleep
import re
from enum import Enum, unique
from difflib import SequenceMatcher
from argparse import ArgumentParser


class Info:
    def __init__(self, key, count):
        self.key = key
        self.count = count
        self.list = []

    def __str__(self):
        return "%s: %s" % (self.count, self.key)


def p(str1):
    if 0:
        print("%s" % str1)


def _wordcount(sub_list, str1):
    found = False
    for info in sub_list:
        ret = SequenceMatcher(None, info.key, str1).quick_ratio()
        if ret >= 0.8:
            found = True
            info.count += 1
            return

    if not found:
        sub_list.append(Info(str1, 1))


def preprocess_line(line):
    # 正则表达式匹配保留有意义的部分，IEWDV 部分
    match = re.match(r'\d{2}-\d{2} \d{2}:\d{2}:\d{2}\.\d{3}  \d+  \d+ ([IEWDV]) (.+)', line)
    if match:
        return f"{match.group(1)} {match.group(2)}"
    # 处理不带时间戳的行
    match_no_timestamp = re.match(r'(.*?): (.*)', line)
    if match_no_timestamp:
        return match_no_timestamp.group(2)
    return line.strip()


# flag1 = 0  # 目标是分段数量
flag_merge = 1  # 目标是thread_count

index_list = None
def do_str_match(all_list, index, lines, start, end, ready_list):
    p("info: do_str_match(%s, %s) BEGIN" % (start, end))

    for i in range(start, end + 1):
        processed_line = preprocess_line(lines[i])
        _wordcount(all_list[index], processed_line)

    p("info: do_str_match(%s, %s) DONE" % (start, end))

    ready_list.append(index)


def do_merge(all_list, index1, index2, ready_list):
    global flag_merge

    sub_list1 = all_list[index1]
    sub_list2 = all_list[index2]

    for info1 in sub_list1:
        for i in range(len(sub_list2)):
            ret = SequenceMatcher(None, info1.key, sub_list2[i].key).quick_ratio()
            if ret > 0.8:
                info1.count += sub_list2[i].count
                sub_list2.__delitem__(i)
                break

    sub_list1.extend(sub_list2)

    ready_list.append(index1)
    flag_merge += 1


if __name__ == '__main__':

    parser = ArgumentParser(description="Log Analysis Tool")
    parser.add_argument('--data_dir', type=str, default='./flask/uploads/1.txt',
                        help='Path to the log file')
    args = parser.parse_args()
    
    # 1.读文件
    with open(args.data_dir, 'r', encoding='utf-8') as f:
        lines = f.readlines()

    # 2.分段
    nrows = len(lines)
    count = 20
    part = nrows // count

    all_list = [[] for i in range(count)]
    ready_list = []

    # 3.分段统计
    threads = []
    for i in range(count):
        begin = i * part
        if i != count - 1:
            end = (i + 1) * part - 1
        else:
            end = nrows - 1

        t = threading.Thread(target=do_str_match, args=(all_list, i, lines, begin, end, ready_list))
        threads.append(t)

    # print(datetime.now())

    for t in threads:
        t.start()

    # 4.周期轮巡
    last_index = 999
    while True:
        sleep(2)

        # 退出条件：分段统计完成 & 字典合并完成
        # print("info: flag_merge=%s len(ready_list)=%s" % (flag_merge, len(ready_list)))
        if flag_merge == count:
            # print("break!")
            break

        # 字典合并
        while len(ready_list) > 1:
            index0 = ready_list[0]
            index1 = ready_list[1]
            if len(all_list[index0]) >= len(all_list[index1]):
                t = threading.Thread(target=do_merge, args=(all_list, index0, index1, ready_list))
                last_index = index0
            else:
                t = threading.Thread(target=do_merge, args=(all_list, index1, index0, ready_list))
                last_index = index1
            threads.append(t)
            t.start()

            ready_list.__delitem__(0)
            ready_list.__delitem__(0)

    for t in threads:
        t.join()

    # print(datetime.now())

    # print("last_index=%s" % last_index)
    # 5.排序
    result = sorted(all_list[last_index], key=lambda x: x.count, reverse=True)
    for info in result:
        print(info)
    # print(datetime.now())

    # # 6.校验总和
    # sum1 = 0
    # for info in result:
    #     print(info)
    #     sum1 += info.count
    # print("info: sum=%s" % sum1)
    # print("*** OVER ***")
